<template>
  <div class="topbarBox">
    <div class="wrap topbarwrap">
      <!-- 顶部左侧 -->
      <div class="left">欢迎来到叩丁狼积分商城</div>
      <!-- 顶部右侧 -->
      <ul class="right">
        <li>
          <img :src="userInfo.headImg" class="userimg" alt="" />
        </li>
        <li>用户名：{{ userInfo.nickName }}</li>
        <li>我的积分： {{ userInfo.coin }}</li>
        <li>获取积分</li>
        <li>叩丁狼官网</li>
        <li class="btn" @click="showModalFn" v-show="!isLogined">登录</li>
        <li class="btn shoppingBtn" v-show="isLogined" @click="$router.push('/user/cart')">
          <img src="@/assets/images/cart.png" alt="" />
          <span class="btnName">购物车</span>
          <span class="shoppingNum">{{ cartTotal }}</span>
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import { mapState, mapMutations, mapActions } from "vuex";
import { WeiXinLoginAPI } from "@/request/api";

export default {
  name: "Topbar",
  created() {
    console.log("created");
    // 可以通过公共组件中获取返回的code值,因为保证在任何页面都能拿到code值
    // 公共组件 如:Topbar,Header,Footer
    //1.通过路由的query方式拿到地址栏的参数
    // console.log(this.$route.query);
    //注意：created钩子函数,此时只对vue对象实例化创建完成,但是还没有初始化完毕，无法拿到地址栏的值
    // 无法确保：是created 先完成 还是 路由对象先完成
    // 解决方案: 路由的钩子函数
    // 作用：等路由对象初始化完毕后，再获取参数

    // 微信扫码登录和监听路由路径变化判断是否已登录
    this.$router.onReady(async () => {
      //1.获取地址栏code的值
      let mycode = this.$route.query.code;

      if (mycode) {
        //2.发送微信扫码登录的请求
        let res = await WeiXinLoginAPI({
          code: mycode,
        });
        //3.微信扫码登录返回的情况:0,400,407
        /*
        0代表成功,
        400请重新扫码，表示code已过期
        407代表需要用户手机再做一次手机号码登录

        注意：当第一次微信扫码登录，会返回407，此时：当code为407时会返回uuid，需要强制用户绑定一次手机号，才能与微信挂钩
      */
        if (res.code == 0) {
          //登录成功
          //1.关闭登录模态框
          this.updateShowModal({ isShowModal: false });
          //2.显示Toast吐司模态框提示: 登录成功
          this.asyncChangeToast({
            isShowToast: true,
            toastMsg: "登录成功",
            toastType: "success",
          });
          //3.把token存储到本地存储
          localStorage.setItem("x-auth-token", res["x-auth-token"]);
          //4.使用完code之后，清除地址栏code,避免重复发送微信扫码登录的请求
          // 直接跳转到当前的路由，this.$route.path
          // console.log(this.$route.path);
          this.$router.push(this.$route.path);
          //5.把登录按钮变为购物车按钮
          this.chanIsLogined({ isLogined: true });
          //6.获取用户信息
          this.asyncChangeUserInfo();
        } else if (res.code == 400) {
          // 二维码超时2min , code已经使用过了，再次发送  都会出现code错误
          //1.code过期的情况,提示请重新扫码
          this.asyncChangeToast({
            isShowToast: true,
            toastMsg: "二维码已失效,请重新扫码",
            toastType: "error",
          });
          //2.弹出登录模态框,并且显示二维码
          this.updateShowModal({
            isShowModal: true,
            loginByModal: "code",
          });
        } else if (res.code == 407) {
          //当用户第一次使用微信扫码登录，并且没有绑定对应的手机号的情况
          //1.提示：用户需要绑定手机号码
          this.asyncChangeToast({
            isShowToast: true,
            toastMsg: "请使用手机号绑定登录微信",
            toastType: "warning",
          });
          //2.把uuid存储到本地中，再进行手机号绑定登录的时候携带uuid
          localStorage.setItem("uuid", res.uuid);
          //3.弹出登录模态框,并显示手机号码登录
          this.updateShowModal({
            isShowModal: true,
            loginByModal: "phone",
          });
          //4.使用完code之后，清除地址栏code,避免重复发送微信扫码登录的请求
          // 直接跳转到当前的路由，this.$route.path
          // console.log(this.$route.path);
          this.$router.push(this.$route.path);
          //当我们关联成功后,之后微信扫码登录都成功。还原407场景，在备份地址扫码登录后解绑即可.
        }
      } else {
        // 方式2的方式：组件重载监听是否登录
        // console.log("步骤3:key属性变化则会重新加载钩子函数");

        //---当页面刷新时候,就判断是否有登录和变更登录状态和用户信息
        //当没有code时,监听是否为登录状态,判断是否有token
        let token = localStorage.getItem("x-auth-token");
        // 更新登录状态
        //写法1
        this.chanIsLogined(Boolean(token));
        //写法2
        // this.chanIsLogined(token ? true : false);
        // 变更登录的信息
        if (token) {
          // 已登录，重新请求用户信息
          this.asyncChangeUserInfo();
        } else {
          // 未登录，还原vuex中userinfo的信息
          this.initUserInfo();
        }


      }
    });
  },

  computed: {
    ...mapState({
      isLogined: (state) => state.loginStatus.isLogined,
      cartTotal: (state) => state.userInfo.cartTotal,
      userInfo: (state) => state.userInfo.userInfo,
    }),
  },
  //需求：手动删除token时,切换导航后更新登录状态。
  //理解：token是登录的依据。当我们已经登录后,把token存储到本地存储,此时当我们手动删除本地的token,而还是处于登录的状态,即路由地址变化也是处于登录的状态
  //监听数据的变化
  //解决方案：
  //方式1：通过watch监听地址变化时,是否还有token
  // watch: {
  //   "$route.path": {
  //     handler(newVal, oldVal) {
  //       console.log(newVal, oldVal);
  //       //当路由地址发送变化,判断token是否还在

  //       //当token判断是否登录，变更登录状态
  //       let token = localStorage.getItem("x-auth-token");
  //       // console.log("token:" + token);
  //       //优化1
  //       // this.chanIsLogined(token ? true : false);
  //       //优化2
  //       // this.chanIsLogined(Boolean(token));
  //       if (token) {
  //         this.chanIsLogined(true);
  //         this.asyncChangeUserInfo();
  //       } else {
  //         //当token不在,表示已经不是登录的状态
  //         this.chanIsLogined(false);
  //         //变更用户的信息
  //         this.initUserInfo();
  //       }
  //     },
  //   },
  // },
  
  //方式2：组件重载， 在App.vue组件
  //1.通过watch监听路由路径的变化
  //2.在Topbar组件中设置唯一标识 :key="num"
  //3.当watch监听到则 num++
  //4.当key属性变化，此时会重新加载钩子函数
  //5.在Topbar中如果没有code则不是登录的时候,我们可以获取本地存储判断是否有token
  // 有token则设置为已登录，无token则未登录

  //方式2：当使用微信扫码的方式登录，有个bug:会出现调用钩子函数两次，显示两次弹框
  /*bug:
    1.当微信扫码的时候，Topbar组件构建完成后并发送登录请求，此时触发了钩子函数，路由路径为: /
    2.当扫码完成后会重定向到指定路由路径，此时再次触发了钩子函数,路由路径为: /home

    解决方案：
    watch监听中，当路由路径是非 / 则进行key++
    此时，相当于只触发了一次
   */

  //总结：两种方式都是通过监听路由路径的变化，再获取本地存储是否有token,从而判断是否变化。
  //即：时刻判断是否是登录的状态。即使手动删除token，当路由路径变化就会监听到，再去获取。
  methods: {
    ...mapMutations({
      updateShowModal: "showModal/updateShowModal",
      chanIsLogined: "loginStatus/chanIsLogined",
      changeUserInfo: "userInfo/changeUserInfo",
      initUserInfo: "userInfo/initUserInfo",
    }),
    ...mapActions({
      asyncChangeToast: "showToast/asyncChangeToast",
      asyncChangeUserInfo: "userInfo/asyncChangeUserInfo",
    }),
    // 登录按钮
    showModalFn() {
      this.updateShowModal({
        isShowModal: true, //是否显示登录模态框
      });
    },
  },
};
</script>

<style lang="less" scoped>
.topbarBox {
  width: 100%;
  height: 40px;
  line-height: 40px;
  background: #242b39;
  border-bottom: 1px solid rgb(48, 57, 74);
  box-sizing: border-box;
  font-size: 14px;
  font-family: SourceHanSansSC;
  font-weight: 300;
  color: #fffefe;
  .topbarwrap {
    display: flex;
    justify-content: space-between;

    .right {
      display: flex;
      justify-content: space-between;

      li {
        margin-left: 20px;
        text-align: center;
        cursor: pointer;
        &.btn {
          width: 124px;
          background: #0a328e;
        }

        &.shoppingBtn {
          font-size: 14px;
          font-family: SourceHanSansSC;
          font-weight: 300;
          color: #fffefe;
          img {
            vertical-align: sub;
          }
          .btnName {
            margin: 0 10px;
          }
          .shoppingNum {
            display: inline-block;
            width: 22px;
            height: 22px;
            line-height: 22px;
            background: #fd604d;
            border-radius: 11px;
          }
        }

        .userimg {
          width: 23px;
          height: 23px;
          border-radius: 50%;
          vertical-align: middle;
        }
      }
    }
  }
}
</style>